import threading
import tkinter
import database
from tkinter import Y,X,LEFT,RIGHT,BOTH,YES,TOP

mainWinConfig={"height":400,"width":720}
mainWinPack={None}

entryConfig={"bg":"black",'fg':"#c0c0c0"}
LeftPanelPack={"fill":Y,"side":LEFT}
LeftPanelConfig={"width":150,"bg":"red","height":200}
leftPanelBreadcrumbConfig={"height":20}
leftPanelBreadcrumbPack={"fill":X}

RightPartConfig={}
RightPartPack={"fill":BOTH,"expand":YES}

searchBarConfig={"height":20}
searchPack={"fill":X}
searchBarEntryConfig={}
searchBarEntryPack={"fill":BOTH,"expand":YES,"side":LEFT}
searchBtnConfig={}
searchBtnPack={"side":RIGHT}

displayMainPartConfig={"padx":20,"pady":10}
displayMainPartPack={"fill":BOTH,"side":TOP,"expand":YES}

imageIconContainerConfig={"height":80,"width":80,"bg":"#602d3f"}
imageIconContainerPack={"side":LEFT}

titleAndVersionContainerConfig={"height":80,"bg":"pink"}
titleAndVersionContainerPack={"fill":BOTH,"side":RIGHT,"expand":YES}

discriptionContainerConfig={"padx":10,"pady":5,"width":250,"height":100}
discriptionContainerPack={"fill":X,"side":TOP,'expand':YES,'anchor':tkinter.NW}

discManPack={"side":LEFT,"fill":BOTH,"expand":YES}
discriptionVersionContainerConfig={"text":"version","padx":10,"pady":10}
discriptionVersionContainerPack={"fill":BOTH,"side":RIGHT,"expand":YES}

menuPack={'side':LEFT,'fill':X,'expand':YES}
rightLabelFramePack={'side':TOP,'fill':X,'anchor':tkinter.N}
buttonsContainerConfig={"pady":10}
buttonsContainerPack={"fill":X,"side":tkinter.BOTTOM}

titleConfig={"font":('Helvetica',20,'bold'),'bg':'yellow'}
titlePack={"fill":X,"side":TOP}

discriptionConfig={"width":32}
discriptionPack={"side":TOP,"anchor":tkinter.W,"fill":Y,"expand":YES}

discriptionVersionConfig={"width":30}
discriptionVersionPack={"fill":BOTH,"expand":YES,"side":TOP}

labelsConfig={}
labelsPack={"side":TOP,"fill":X}

upperSideConfig={"pady":10}
upperSidePack={"fill":X,"side":TOP}

openPathBTNConfig={}
openPathBTNPack={"side":RIGHT,"expand":tkinter.NO}


con=database.sqliteDB("test.sqlite")
con.openConnection()
class mainUi( tkinter.Tk ):
    """
    display main window
    """
    def __init__(self):
        """
        initiate Window
        """
        self.currentPosition={'nowC':None,'typeC':None,'groupC':None,'records':None}
        tkinter.Tk.__init__(self)
        self.__leftPanel=leftPanel(self)
        self.__leftPanel.config(LeftPanelConfig)
        self.__leftPanel.pack_propagate(0)
        self.__leftPanel.pack(LeftPanelPack)
        self.__Breadcrumb=tkinter.Frame(self.__leftPanel)
        self.__Breadcrumb.config(leftPanelBreadcrumbConfig)
        self.__Breadcrumb.pack(leftPanelBreadcrumbPack)
        self.__BackBTN=tkinter.Button(self.__Breadcrumb,text='back',command=lambda :self.goBack())
        self.__BackBTN.pack({"fill":BOTH})
        #self.resizable(0,0)


        self.pack_propagate(0)

        self.__nav=tkinter.Frame(self.__leftPanel)
        self.__nav.config()
        self.__nav.pack({"fill":BOTH})

        self.__rightPart=tkinter.Frame(self)
        self.__rightPart.pack_propagate(0)
        self.__rightPart.config(RightPartConfig)
        self.__searchBar=tkinter.Frame(self.__rightPart)
        self.__searchBar.config(searchBarConfig)
        self.__searchBtn=tkinter.Button(self.__searchBar,text="search")
        self.__searchBtn.config(searchBtnConfig)
        self.__searchBarEntry=tkinter.Entry(self.__searchBar)
        self.__searchBarEntry.config(searchBarEntryConfig)
        self.__searchBarEntry.pack(searchBarEntryPack)
        self.__searchBtn.pack(searchBtnPack)
        self.__searchBar.pack(searchPack)
        self.displayMainPart=displayMain(self.__rightPart)
        self.displayMainPart.config(displayMainPartConfig)
        self.displayMainPart.pack_propagate(0)
        self.displayMainPart.pack(displayMainPartPack)
        self.__rightPart.pack(RightPartPack)
        self.config(mainWinConfig)

    def goBack(self):
        """
        go back in list
        """
        if self.currentPosition['nowC'] == 'group':
            self.navChangeView('type',self.currentPosition['typeC'])
        elif self.currentPosition['nowC'] == 'records':
            self.navChangeView('group',self.currentPosition['typeC'])
        elif self.currentPosition['nowC'] == 'version':
            self.navChangeView('records',self.currentPosition['groupC'])
            out =  con.ListAll('records',self.currentPosition['records'],refer='*',backWard=True)
            out[0]['type']='version'
            self.displayMainPart.drawEntryDetail(out[0])
        
    def navChangeView(self , whereTo, parentId ):
        """
        change navigation view

        whereTo -- display which kind of items??
        parentId  -- constrain of which items to display
        """
        """
        maybe change to navChangeView(self, whereTo(dict{'
        """
        print("______",whereTo)
        if type(whereTo) == type(dict()):
            whereTo=whereTo['type']
        elif whereTo=='root':
            whereTo='type'
        if whereTo == self.currentPosition['nowC']:
            return
        else:
            self.currentPosition['nowC']=whereTo
            if whereTo == 'type' :
                out = con.listAllInType()
                whereTo = 'group'
            elif whereTo == 'group':
                self.currentPosition['typeC']=parentId
                out = con.ListAll(whereTo,parentId)
                whereTo = 'records'
            elif whereTo == 'records':
                out = con.ListAll(whereTo,parentId)
                self.currentPosition['groupC']=parentId
                whereTo = 'version'
            elif whereTo == 'version':
                out = con.ListAll(whereTo,parentId)
                self.currentPosition['records']=parentId
                whereTo='detail'
            for li in self.__nav.slaves():
                li.destroy()
            if whereTo != 'detail': 
                for  li in out:
                    li['type']=whereTo
                    anewEntry=navEntry(self.__nav,li, [self.navChangeView] + [(self.displayMainPart.drawEntryDetail if whereTo == 'version' else None )])
                    anewEntry.config(entryConfig)
                    anewEntry.pack({"fill":X})
            else:
                for li in out:
                    li['type']=whereTo
                    ddd=navEntry(self.__nav,li, [self.displayMainPart.drawEntryDetail])
                    ddd.config(entryConfig)
                    ddd.pack({"fill":X})
            print('position',self.currentPosition)
        self.title("dd")

class leftPanel( tkinter.Frame ):
    """
    Display left navigation part
    """
    def __init__( self,parent ):
        tkinter.Frame.__init__(self,parent)


class displayMain(tkinter.Frame):
    mainRecord=''
    versionRecord=''
    """
    This class represents main diaplay Part
    """
    def __init__(self, parent):
        """
        Constructor.
        parent -- widget parent
        entryId -- id of entry
        """
        tkinter.Frame.__init__(self,parent)
    """
    TODO:
        1. fill code
    """
    def drawEntryDetail(self, entryInfo ,typeTrash=None):
        """
        display entry detail
        entryId -- id of entry
        """
        

        for i in self.slaves():
            i.destroy()
        "Icon and discriptyion"
        self.upperSide=tkinter.Frame(self)
        self.upperSide.config(upperSideConfig)
        self.titleAndVersionContainer=tkinter.Frame(self.upperSide)
        self.titleAndVersionContainer.config(titleAndVersionContainerConfig)
        self.title=tkinter.Label(self.titleAndVersionContainer,text="foobar2k")
        self.title.config(titleConfig)
        self.imageIconContainer=tkinter.Frame(self.upperSide)
        self.imageIconContainer.config(imageIconContainerConfig)

        self.upperSide.pack(upperSidePack)
        self.imageIconContainer.pack(imageIconContainerPack)
        self.titleAndVersionContainer.pack(titleAndVersionContainerPack)
        self.title.pack(titlePack)

        "footer"
        self.buttonsContainer=tkinter.Frame(self)
        self.buttonsContainer.config(buttonsContainerConfig)
        self.openPathBTN=tkinter.Button(self.buttonsContainer,text="Open")
        self.openPathBTN.config(openPathBTNConfig)
        self.buttonsContainer.pack(buttonsContainerPack)
        self.openPathBTN.pack(openPathBTNPack)

        "discriptyion label etc--Varies by version and main record"
        if entryInfo['type'] == 'version':
            displayMain.mainRecord=entryInfo

            self.discMain=tkinter.Frame(self)
            self.discMain.config({})
            self.discription=tkinter.Text(self.discMain)
            self.discription.config(discriptionConfig)
            self.discMain.pack_propagate(0)
            self.discMain.pack(discManPack)
            tkinter.Label(self.discMain,text='discription:',anchor=tkinter.W).pack({"side":TOP,"fill":X})
            self.discription.pack(discriptionPack)

            self.rightSide=tkinter.Frame(self)
            self.rightSide.config()
            self.rightSide.pack(discriptionContainerPack)
            self.rightSoftInfo=tkinter.LabelFrame(self.rightSide,text="Software Info")
            self.rightSoftInfo.config(discriptionContainerConfig)
            self.labelFrame=tkinter.Frame(self.rightSoftInfo)
            self.labelFrame.config({"pady":1})
            self.labels=tkinter.Entry(self.labelFrame)
            self.labels.config(labelsConfig)
            self.urlFrame=tkinter.Frame(self.rightSoftInfo)
            self.urlFrame.config({'pady':1})
            self.url=tkinter.Entry(self.urlFrame)
            self.url.config()
            self.rightSoftInfo.pack_propagate(0)
            self.rightSoftInfo.pack()
            self.labelFrame.pack({"fill":X})
            tkinter.Label(self.labelFrame,text='Labels:',anchor=tkinter.W).pack({"side":TOP,"fill":X})
            self.labels.pack(labelsPack)
            self.urlFrame.pack({'fill':X})
            tkinter.Label(self.labelFrame,text='Url:',anchor=tkinter.W).pack({"side":TOP,"fill":X})
            self.url.pack({'fill':X})

            self.position=tkinter.LabelFrame(self.rightSide,text="Position")
            self.position.config({'padx':10,'pady':10})
            alltypes=con.listAllInType()
            tmpDefault=con.getTypeByRecordName(entryInfo['name'])
            tmpDefault['type']='type'
            self.typePostion=dropDownlist(self.position,alltypes,tmpDefault,self.changePosition)
            #tkinter.Label(self.position,text='Types:',anchor=tkinter.W).pack({"side":TOP,"fill":X})
            self.typePostion.pack(menuPack)
            tmpList=con.listAllInType(tableType='group')
            tmpDefault=con.getGroupByRecordName(entryInfo['name'])
            tmpDefault['type']='group'
            self.groupPostion=dropDownlist(self.position,tmpList,tmpDefault,self.changePosition)
            #tkinter.Label(self.position,text='groups:',anchor=tkinter.W).pack({"side":TOP,"fill":X})
            self.groupPostion.pack(menuPack)
            self.position.pack(rightLabelFramePack)

            self.mainVerion=tkinter.LabelFrame(self.rightSide,text="mainVersion")
            self.mainVerion.config({'padx':10,'pady':10})
            tmpList=con.ListAll('version',entryInfo['id'])
            tmpDefault=con.getDefaultVersion(entryInfo['id'])
            self.mainVersionSelect=dropDownlist(self.mainVerion,tmpList,tmpDefault,self.changePosition)
            self.mainVersionSelect.pack(menuPack)
            self.mainVerion.pack(rightLabelFramePack)


        else:
            displayMain.versionRecord=entryInfo
            self.discriptionVersionContainer=tkinter.LabelFrame(self)
            self.discriptionVersionContainer.config(discriptionVersionContainerConfig)
            self.discriptionVersion=tkinter.Text(self.discriptionVersionContainer)
            self.discriptionVersion.config(discriptionVersionConfig)

            self.discriptionVersionContainer.pack(discriptionVersionContainerPack)
            self.discriptionVersion.pack(discriptionVersionPack)

        print("MainWin Drowed",entryInfo)
    def changePosition(self, changeWhichPostion, toWhere):
        """
        change the position of a record
        
        changeWhichPostion -- change which?(table name)
        toWhere -- to what value
        """
        print(changeWhichPostion,"changed to ",toWhere)
        return
        
    """
    TODO:
        1. fill code
    """
    def drawList(self, listDetailDir):
        """
        draw a list of any thing put in 
        listDetailDir -- list detail (dictionary)
        """
        return 1

class dropDownlist(tkinter.Menubutton):
    """
    This class represents dropdownlist
    """

    def changeDropdownText(self, selectedInfo):
        """
        change dropdownlist selected
        
        selectedInfo -- dire of selected info
        """
        self.config({'text':selectedInfo['name']})
        self.onclicked(self.typeD['type'],selectedInfo['id'])

    def __init__(self, parent,menuList,initialValue,onclicked):
        """
        Constructor.
        
        parent   -- parent
        menuList -- list of menu
        initialValue     -- name of menu
        """
        tkinter.Menubutton.__init__(self,parent,{'relief':tkinter.RAISED})
        self.onclicked=onclicked
        self.typeD=initialValue.copy()
        self.picks=tkinter.Menu(self,{'tearoff':0})
        self.config({'justify':tkinter.CENTER})
        self.config({'text':self.typeD['name'],'menu':self.picks})
        for i in menuList:
            self.picks.add_command(label=i['name'],command=( lambda i=i : self.changeDropdownText(i) ))

class navEntry(tkinter.Label):
    """
    This class represents entry in navigation
    """
    def recordEventHandler(eventList,paras):
        """
        go 2 methods 
        
        eventList -- method list
        """
        for event in eventList:
            if event != None:
                print("calling")
                event(paras,paras['id'])
    def __init__(self,parent, entryInfo,onClick):
        """
        Constructor.

        parent    -- parent widget
        entryInfo -- infomation of entry dir{"type":?,"id":?,"name":?}
        onClick   -- eventHandler List
        """
        tkinter.Label.__init__(self,parent,text=(entryInfo['type']+entryInfo['name']+str(entryInfo['id'])))
        if entryInfo['type']=='detail':
            out =  con.ListAll('version',entryInfo['id'],refer='*')
        else:
            out =  con.ListAll(entryInfo['type'],entryInfo['id'],refer='*')
        self.bind('<Button-1>',lambda event: navEntry.recordEventHandler(onClick,entryInfo))

class searchThread(threading.Thread):
    """
    This class represents 
    """
    outData=[1]
    def __init__(self,labels):
        """
        Constructor.

        labels -- labels 
        """
        self.conn=database.sqliteDB('test.sqlite')
        self.labels=labels
        threading.Thread.__init__(self)

    def run(self):
        """
        search

        target -- id
        """
        self.conn.openConnection()
        searchThread.outData=self.conn.searchRecordByLabels(self.labels)
        print("before",threading.currentThread())
        print("threaded",threading.currentThread(),searchThread.outData)
        shitCon.acquire()
        shitCon.notify()
        shitCon.release()
        self.conn.closeConnection()

if __name__ == '__main__':
    tet=mainUi()
    #print(con.ListAll('type',refer='*'))
    tet.navChangeView('root',0)
    #tasdf=searchThread('test')
    #tasdf.start()
    #shitCon=threading.Condition()
    #shitCon.acquire()
    #while True:
    #    print("main",searchThread.outData)
    #    shitCon.wait()
    tet.mainloop()
    con.comitChanges()
    con.closeConnection()

